package service

import (
	"context"
	"errors"
	"pmservice/db"
	"pmservice/graph/model"
)

var (
	EcmModels = map[string]*model.EcmModel{
		"ECG_D600": {
			Modelname:      "ECG_D600",
			Modelvalue:     0,
			Ecgsamplerate:  500,
			Ecgvalpermv:    780,
			Respsamplerate: 250,
			Respvalpermv:   500,
			Spo2samplerate: 500,
			Spo2valpermv:   300,
		},
		"ECG_D1000": {
			Modelname:      "ECG_D1000",
			Modelvalue:     0,
			Ecgsamplerate:  500,
			Ecgvalpermv:    780,
			Respsamplerate: 250,
			Respvalpermv:   500,
			Spo2samplerate: 500,
			Spo2valpermv:   300,
		},
	}
)

func EcgModelGet(model string) *model.EcmModel {
	for _, v := range EcmModels {
		if v.Modelname == model {
			return v
		}
	}
	return nil
}

// EcmNew is the resolver for the EcmNew field.
func (s *Service) EcmNew(ctx context.Context, input model.EcmNew) (*model.ElectroCardiacMonitor, error) {
	if EcgModelGet(input.Model) == nil {
		return nil, errors.New("ecm model not found")
	}

	hos := db.HospitalGet(s.Orm.DB, input.Hosuid)
	if hos == nil {
		return nil, errors.New("hos not found")
	}

	if db.EcmExist(s.Orm.DB, input.Hosuid, "", input.Code) {
		return nil, errors.New("code been used")
	}

	d, err := db.EcmNew(s.Orm.DB, &input)
	if err != nil {
		return nil, err
	}

	return s.EcmGet(ctx, d.UID, "")
}

// EcmSave is the resolver for the EcmSave field.
func (s *Service) EcmSave(ctx context.Context, uid string, input model.EcmEdit) (bool, error) {
	ecm := db.EcmGet(s.Orm.DB, uid)
	if ecm == nil {
		return false, errors.New("ecm not found")
	}

	if input.Code != nil && db.EcmExist(s.Orm.DB, ecm.Hospital, uid, *input.Code) {
		return false, errors.New("code been used")
	}

	return db.EcmSave(s.Orm.DB, ecm.Hospital, uid, &input), nil
}

// EcmDelete is the resolver for the EcmDelete field.
func (s *Service) EcmDelete(ctx context.Context, uid string) (bool, error) {
	return db.EcmDel(s.Orm.DB, uid), nil
}

func (s *Service) EcmGetCompositeData(ctx context.Context, d *db.Ecm, prefix string) (*model.ElectroCardiacMonitor, error) {
	ret := d.ToGQL()
	if HasField(ctx, PrefixJoin(prefix, "model")) {
		ret.Model = EcgModelGet(d.DevModel)
	}

	if HasField(ctx, PrefixJoin(prefix, "hospital")) {
		ret.Hospital, _ = s.HospitalGet(ctx, d.Hospital, PrefixJoin(prefix, "hospital"))
	}

	if HasField(ctx, PrefixJoin(prefix, "poc")) {
		ret.Poc, _ = s.PocGetByInstalledEcm(ctx, d.UID, PrefixJoin(prefix, "poc"))
	}

	return ret, nil
}

// EcmGet is the resolver for the EcmGet field.
func (s *Service) EcmGet(ctx context.Context, uid string, prefix string) (*model.ElectroCardiacMonitor, error) {
	d := db.EcmGet(s.Orm.DB, uid)
	if d == nil {
		return nil, errors.New("ecm not found")
	}

	return s.EcmGetCompositeData(ctx, d, prefix)
}

// EcmModelGet is the resolver for the EcmModelGet field.
func (s *Service) EcmModelGet(ctx context.Context) ([]*model.EcmModel, error) {
	ret := make([]*model.EcmModel, 0)
	for _, v := range EcmModels {
		ret = append(ret, v)
	}
	return ret, nil
}

// EcmGetByCode is the resolver for the EcmGetByCode field.
func (s *Service) EcmGetByCode(ctx context.Context, hosuid string, code int, prefix string) (*model.ElectroCardiacMonitor, error) {
	d := db.EcmGetByCode(s.Orm.DB, hosuid, code)
	if d == nil {
		return nil, errors.New("ecm not found")
	}

	return s.EcmGetCompositeData(ctx, d, prefix)
}

// EcmSearch is the resolver for the EcmSearch field.
func (s *Service) EcmSearch(ctx context.Context, cond model.EcmSearchCond, prefix string) (*model.EcmSearchResult, error) {
	ecms, total := db.EcmSearch(s.Orm.DB, cond)
	ret := model.EcmSearchResult{
		Results: make([]*model.ElectroCardiacMonitor, 0),
		Total:   int(total),
	}

	for _, e := range ecms {
		ecm, _ := s.EcmGetCompositeData(ctx, e, prefix)
		if ecm != nil {
			ret.Results = append(ret.Results, ecm)
		}
	}

	return &ret, nil
}
